﻿using System;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using AppLimit.CloudComputing.SharpBox;
using AppLimit.CloudComputing.SharpBox.StorageProvider.DropBox;
using RuTracker.Interface.Dropbox;
using RuTrackerLib;
using RuTrackerLib.Storage;

namespace RuTracker.MVC.Core
{
    public class DropboxAdapter
    {
        private readonly HttpSessionStateBase _session;

        public DropboxAdapter(HttpSessionStateBase session, byte[] token = null)
        {
            _session = session;
            if (token != null)
                Token = token;
        }
        
        public bool IsLoggedIn
        {
            get { return _session["DropBoxToken"] != null; }
        }

        public byte[] Token
        {
            get { return _session["DropBoxToken"] as byte[]; }
            private set { _session["DropBoxToken"] = value; }
        }

        public StorageFolder RootFolder 
        {
            get { return _session["DropBoxRootFolder"] as StorageFolder; }
            private set { _session["DropBoxRootFolder"] = value; }
        }

        public DropBoxRequestToken ReuqestedToken
        {
            get { return _session["RequestToken"] as DropBoxRequestToken; }
            private set { _session["RequestToken"] = value; }
        }

        public void Reset()
        {
            ReuqestedToken = null;
            Token = null;
            RootFolder = null;
        }

        public string RequestForToken(string callbackUrl)
        {
            string authorizationUrl = string.Empty;

            try
            {
                DropBoxConfiguration config = CloudStorage.GetCloudConfigurationEasy(nSupportedCloudConfigurations.DropBox) as DropBoxConfiguration;
                config.AuthorizationCallBack = new Uri(callbackUrl);
                DropBoxRequestToken requestToken = DropBoxStorageProviderTools.GetDropBoxRequestToken(config, AppKey, SecretKey);
                authorizationUrl = DropBoxStorageProviderTools.GetDropBoxAuthorizationUrl(config, requestToken);

                ReuqestedToken = requestToken;
                
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
                Log.Error(ex, "Error during requesting token from drop box ");
            }

            return authorizationUrl;

        }

        public bool Login()
        {
            bool result = false;
            if (ReuqestedToken != null)
            {
                try
                {
                    DropBoxConfiguration config = CloudStorage.GetCloudConfigurationEasy(nSupportedCloudConfigurations.DropBox) as DropBoxConfiguration;
                    var authtocken = DropBoxStorageProviderTools.ExchangeDropBoxRequestTokenIntoAccessToken(config, AppKey, SecretKey, ReuqestedToken);
                    CloudStorage dropBoxStorage = new CloudStorage();
                    dropBoxStorage.Open(config, authtocken);
                    using (Stream stream = dropBoxStorage.SerializeSecurityToken(authtocken))
                    {
                        byte[] buffer = new byte[stream.Length];
                        stream.Read(buffer, 0, buffer.Length);
                        Token = buffer;
                    }

                    dropBoxStorage.Close();
                    result = true;
                }
                catch (Exception ex)
                {
                    Log.Error(ex, "Error during logging to drop box ");
                }
            }
            return result;
        }

        public StorageFolder ResolveStorageFolder()
        {
            if (RootFolder == null)
            {
                using (DropBoxAccessor accessor = new DropBoxAccessor())
                {
                    accessor.Connect(Token);
                    RootFolder = accessor.LoadHierarchy();
                }
            }
            return RootFolder;
        }

        private string SecretKey
        {
            get { return ConfigurationManager.AppSettings["DropBoxSecretKey"]; }
        }

        private string AppKey
        {
            get { return ConfigurationManager.AppSettings["DropBoxAppKey"]; }
        }
    }
}